package com.pdjs.code.utils.uptranslit.core;

import java.util.HashMap;



public class WordTransliterator {
	
    private static WordTransliterator instance = new WordTransliterator();
        
	private static HashMap<String,String> dependent_vowels_map;
	private static HashMap<String,String> independent_vowels_map;
	private static HashMap<String,String> consonants_map;
	private static char halant_const = '\u094D';

	private WordTransliterator() {
            dependent_vowels_map = new HashMap<String,String>();
            independent_vowels_map = new HashMap<String,String>();
            consonants_map = new HashMap<String,String>();            
            setUpMaps();		
	}
        
        public static WordTransliterator getInstance() {
            return instance;
        }
	
	private void setUpMaps() {
		
		if (dependent_vowels_map.size() == 0) {
			dependent_vowels_map.put("a","\u0905");
			dependent_vowels_map.put("aa","\u093E");
			dependent_vowels_map.put("i","\u093F");
			dependent_vowels_map.put("ii","\u0940");
			dependent_vowels_map.put("u","\u0941");
			dependent_vowels_map.put("uu","\u0942");
			dependent_vowels_map.put("e","\u0947");
			dependent_vowels_map.put("ai","\u0948");
			dependent_vowels_map.put("o","\u094B");
			dependent_vowels_map.put("au","\u094C");
		}
		
		if (independent_vowels_map.size() == 0) {
			independent_vowels_map.put("a","\u0905");
			independent_vowels_map.put("aa","\u0906");
			independent_vowels_map.put("i","\u0907");
			independent_vowels_map.put("ii","\u0908");
			independent_vowels_map.put("u","\u0909");
			independent_vowels_map.put("uu","\u090A");
			independent_vowels_map.put("e","\u090F");
			independent_vowels_map.put("ai","\u0910");
			independent_vowels_map.put("o","\u0913");
			independent_vowels_map.put("au","\u0914");
            independent_vowels_map.put(".n","\u0902");
			independent_vowels_map.put(".N","\u0901");
		}
		
		if (consonants_map.size() == 0) {
			consonants_map.put("b","\u092C");
			consonants_map.put("bh","\u092D");
			consonants_map.put("ch","\u091A");
			consonants_map.put("chh","\u091B");
			consonants_map.put("d","\u0926");
			consonants_map.put("dh","\u0927");
			consonants_map.put("D","\u0921");
			consonants_map.put("Dh","\u0922");
			consonants_map.put(".D","\u095C");
			consonants_map.put(".Dh","\u095D");
			consonants_map.put("f","\u092B\u093C");
			consonants_map.put("g","\u0917");
			consonants_map.put("gh","\u0918");
			consonants_map.put("G","\u095A");
			consonants_map.put("h","\u0939");
			consonants_map.put("j","\u091C");
			consonants_map.put("k","\u0915");
			consonants_map.put("kh","\u0916");
			consonants_map.put("Kh","\u0959");
			consonants_map.put("l","\u0932");
			consonants_map.put("m","\u092E");
			consonants_map.put("n","\u0928");
			consonants_map.put("p","\u092A");
			consonants_map.put("ph","\u092B\u093C");
			consonants_map.put("q","\u0958");
			consonants_map.put("r","\u0930");
			consonants_map.put("s","\u0938");
			consonants_map.put("t","\u0924");
			consonants_map.put("th","\u0925");
			consonants_map.put("T","\u091F");
			consonants_map.put("Th","\u0920");
			consonants_map.put("v","\u0935");
            consonants_map.put("w","\u0935");
			consonants_map.put("y","\u092F");
			consonants_map.put("z","\u095B");
            consonants_map.put("Z","\u095B");
			consonants_map.put("jh","\u091D");
            consonants_map.put("sh","\u0936");
            consonants_map.put("F","\u095E");
		}
	}	
	
	
	public String translitertate(String englishWord) {		
		//StringBuffer sbuff = new StringBuffer();
        Result result = new Result();
		if (englishWord != null && !"".equals(englishWord.trim())) {
			
			int parse_idx = 0; 
			char[] word_arr = englishWord.toCharArray();
			do {
				if (!parseW(word_arr,result,parse_idx,3)) {//try to parse 3 characters
					
					if (!parseW(word_arr,result,parse_idx,2)) {//try to parse 2 characters
						
						if (!parseW(word_arr,result,parse_idx,1)) {//try to parse 1 character
                            removeLastHalant(result); // remove last halant if any
							result.getSbuff().append(word_arr[parse_idx++]); //not in dictionary append character as it is
						} else {
							parse_idx++; //parse the next characters
						}
					} else { // parse the next characters
						parse_idx += 2;
					}
				} else {//parse the next characters
					parse_idx +=3;
				}
				
			}while(parse_idx < englishWord.length());
			
		}
		removeLastHalant(result);
		return result.getSbuff().toString();
	}	

	private static boolean parseW(char[] word_arr, Result resultobj,int parse_idx, int parse_count) {

        boolean result = false;
		if (parse_idx >= word_arr.length || (parse_idx + parse_count > word_arr.length)) return result;
		
		String temp_str = new String(word_arr,parse_idx,parse_count);
		
		if (parse_idx == 0 || resultobj.isIslaskOK()) {//check for independent vowel
			if (independent_vowels_map.containsKey(temp_str)) {
				resultobj.getSbuff().append(independent_vowels_map.get(temp_str));
                resultobj.setIslaskOK(true);//search for idenpendent vowel or consonant next time
				result = true;
			} 
		} 
        if  (!result && !resultobj.isIslaskOK() && dependent_vowels_map.containsKey(temp_str)) {

            removeLastHalant(resultobj);
            if (!"a".equals(temp_str)) {
                resultobj.getSbuff().append(dependent_vowels_map.get(temp_str));                
            }
            resultobj.setIslaskOK(true);
            result = true;
        } 			
		
		if (!result && consonants_map.containsKey(temp_str)) {
			resultobj.getSbuff().append(consonants_map.get(temp_str));
			resultobj.getSbuff().append(halant_const);//append halant by default
            resultobj.setIslaskOK(false);
			result = true;
		}
		
		//System.out.println("temp_str "+ temp_str + " parse_idx-->"+parse_idx+ " parse_count-->"+parse_count+" sbuff-->"+resultobj.getSbuff().toString());
		return result;
	}
	
	private static void removeLastHalant(Result result) {
        StringBuffer sbuff = result.getSbuff();
		if (sbuff == null || sbuff.length()==0) return;
		char last_ucode = sbuff.charAt(sbuff.length()-1);
		if (halant_const == last_ucode) {
			sbuff.deleteCharAt(sbuff.length()-1);
		} 
	}


//	public static void main(String[] args) {
//		try {
//			WordTransliterator wt = new WordTransliterator();
//			System.out.println(wt.translitertate("duaae.n"));
//		} catch (Exception ex) {
//			ex.printStackTrace();
//		}
//	}

}

class Result {
    private StringBuffer sbuff = new StringBuffer();


    public boolean isIslaskOK() {
        return islaskOK;
    }

    public void setIslaskOK(boolean islaskOK) {
        this.islaskOK = islaskOK;
    }

    public StringBuffer getSbuff() {
        return sbuff;
    }

    public void setSbuff(StringBuffer sbuff) {
        this.sbuff = sbuff;
    }
    private boolean islaskOK;
    
}



